From f768ae4281bce4162c81e745e48b9d464e518fb2 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Tue, 16 Jan 2018 13:52:40 -0500 Subject: [PATCH] menushell: Stop using ::button-press/release-event Merge the handlers into the existing handler for ::event. --- gtk/gtkmenushell.c | 327 +++++++++++++++++++++------------------------ 1 file changed, 153 insertions(+), 174 deletions(-) diff --git a/gtk/gtkmenushell.c b/gtk/gtkmenushell.c index efc6fcbdfe..a0bdf00a30 100644 --- a/gtk/gtkmenushell.c +++ b/gtk/gtkmenushell.c @@ -116,10 +116,6 @@ static void gtk_menu_shell_get_property (GObject *object, GParamSpec *pspec); static void gtk_menu_shell_finalize (GObject *object); static void gtk_menu_shell_dispose (GObject *object); -static gint gtk_menu_shell_button_press (GtkWidget *widget, - GdkEventButton *event); -static gint gtk_menu_shell_button_release (GtkWidget *widget, - GdkEventButton *event); static gint gtk_menu_shell_key_press (GtkWidget *widget, GdkEventKey *event); static void gtk_menu_shell_display_changed (GtkWidget *widget, @@ -178,8 +174,6 @@ gtk_menu_shell_class_init (GtkMenuShellClass *klass) object_class->finalize = gtk_menu_shell_finalize; object_class->dispose = gtk_menu_shell_dispose; - widget_class->button_press_event = gtk_menu_shell_button_press; - widget_class->button_release_event = gtk_menu_shell_button_release; widget_class->event = gtk_menu_shell_event; widget_class->key_press_event = gtk_menu_shell_key_press; widget_class->display_changed = gtk_menu_shell_display_changed; @@ -604,82 +598,6 @@ gtk_menu_shell_get_toplevel_shell (GtkMenuShell *menu_shell) return menu_shell; } -static gint -gtk_menu_shell_button_press (GtkWidget *widget, - GdkEventButton *event) -{ - GtkMenuShell *menu_shell; - GtkMenuShellPrivate *priv; - GtkWidget *menu_item; - - menu_shell = GTK_MENU_SHELL (widget); - priv = menu_shell->priv; - - menu_shell = GTK_MENU_SHELL (widget); - priv = menu_shell->priv; - menu_item = gtk_get_event_target_with_type ((GdkEvent *) event, GTK_TYPE_MENU_ITEM); - - if (menu_item && - _gtk_menu_item_is_selectable (menu_item) && - gtk_widget_get_parent (menu_item) == widget) - { - if (menu_item != menu_shell->priv->active_menu_item) - { - /* select the menu item *before* activating the shell, so submenus - * which might be open are closed the friendly way. If we activate - * (and thus grab) this menu shell first, we might get grab_broken - * events which will close the entire menu hierarchy. Selecting the - * menu item also fixes up the state as if enter_notify() would - * have run before (which normally selects the item). - */ - if (GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement != GTK_TOP_BOTTOM) - gtk_menu_shell_select_item (menu_shell, menu_item); - } - - if (GTK_MENU_ITEM (menu_item)->priv->submenu != NULL && - !gtk_widget_get_visible (GTK_MENU_ITEM (menu_item)->priv->submenu)) - { - _gtk_menu_item_popup_submenu (menu_item, FALSE); - priv->activated_submenu = TRUE; - } - } - - if (!priv->active || !priv->button) - { - gboolean initially_active = priv->active; - guint button; - guint32 time; - - gdk_event_get_button ((GdkEvent *)event, &button); - time = gdk_event_get_time ((GdkEvent *)event); - - priv->button = button; - - if (menu_item) - { - if (_gtk_menu_item_is_selectable (menu_item) && - gtk_widget_get_parent (menu_item) == widget && - menu_item != priv->active_menu_item) - { - gtk_menu_shell_activate (menu_shell); - - if (GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement == GTK_TOP_BOTTOM) - { - priv->activate_time = time; - gtk_menu_shell_select_item (menu_shell, menu_item); - } - } - } - else if (!initially_active) - { - gtk_menu_shell_deactivate (menu_shell); - return FALSE; - } - } - - return TRUE; -} - static gboolean gtk_menu_shell_event (GtkWidget *widget, GdkEvent *event) @@ -701,135 +619,196 @@ gtk_menu_shell_event (GtkWidget *widget, return GDK_EVENT_STOP; } + else if (gdk_event_get_event_type (event) == GDK_BUTTON_PRESS) + { + GtkWidget *menu_item; - return GDK_EVENT_PROPAGATE; -} + menu_item = gtk_get_event_target_with_type (event, GTK_TYPE_MENU_ITEM); -static gint -gtk_menu_shell_button_release (GtkWidget *widget, - GdkEventButton *event) -{ - GtkMenuShell *menu_shell = GTK_MENU_SHELL (widget); - GtkMenuShellPrivate *priv = menu_shell->priv; - GtkMenuShell *parent_shell = GTK_MENU_SHELL (priv->parent_menu_shell); - gboolean activated_submenu = FALSE; - guint new_button; - guint32 time; + if (menu_item && + _gtk_menu_item_is_selectable (menu_item) && + gtk_widget_get_parent (menu_item) == widget) + { + if (menu_item != menu_shell->priv->active_menu_item) + { + /* select the menu item *before* activating the shell, so submenus + * which might be open are closed the friendly way. If we activate + * (and thus grab) this menu shell first, we might get grab_broken + * events which will close the entire menu hierarchy. Selecting the + * menu item also fixes up the state as if enter_notify() would + * have run before (which normally selects the item). + */ + if (GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement != GTK_TOP_BOTTOM) + gtk_menu_shell_select_item (menu_shell, menu_item); + } - gdk_event_get_button ((GdkEvent *)event, &new_button); - time = gdk_event_get_time ((GdkEvent *)event); + if (GTK_MENU_ITEM (menu_item)->priv->submenu != NULL && + !gtk_widget_get_visible (GTK_MENU_ITEM (menu_item)->priv->submenu)) + { + _gtk_menu_item_popup_submenu (menu_item, FALSE); + priv->activated_submenu = TRUE; + } + } - if (parent_shell) - { - /* If a submenu was just activated, it is its shell which is receiving - * the button release event. In this case, we must check the parent - * shell to know about the submenu state. - */ - activated_submenu = parent_shell->priv->activated_submenu; - parent_shell->priv->activated_submenu = FALSE; - } + if (!priv->active || !priv->button) + { + gboolean initially_active = priv->active; + guint button; + guint32 time; - if (priv->parent_menu_shell && - (time - GTK_MENU_SHELL (priv->parent_menu_shell)->priv->activate_time) < MENU_SHELL_TIMEOUT) - { - /* The button-press originated in the parent menu bar and we are - * a pop-up menu. It was a quick press-and-release so we don't want - * to activate an item but we leave the popup in place instead. - * https://bugzilla.gnome.org/show_bug.cgi?id=703069 - */ - GTK_MENU_SHELL (priv->parent_menu_shell)->priv->activate_time = 0; - return GDK_EVENT_STOP; - } + gdk_event_get_button (event, &button); + time = gdk_event_get_time (event); - if (priv->active) + priv->button = button; + + if (menu_item) + { + if (_gtk_menu_item_is_selectable (menu_item) && + gtk_widget_get_parent (menu_item) == widget && + menu_item != priv->active_menu_item) + { + gtk_menu_shell_activate (menu_shell); + + if (GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement == GTK_TOP_BOTTOM) + { + priv->activate_time = time; + gtk_menu_shell_select_item (menu_shell, menu_item); + } + } + } + else if (!initially_active) + { + gtk_menu_shell_deactivate (menu_shell); + return GDK_EVENT_STOP; + } + } + + return GDK_EVENT_PROPAGATE; + } + else if (gdk_event_get_event_type (event) == GDK_BUTTON_RELEASE) { - GtkWidget *menu_item; - gint button = priv->button; + GtkMenuShell *parent_shell = GTK_MENU_SHELL (priv->parent_menu_shell); + gboolean activated_submenu = FALSE; + guint new_button; + guint32 time; - priv->button = 0; + gdk_event_get_button (event, &new_button); + time = gdk_event_get_time (event); - if (button && (new_button != button) && priv->parent_menu_shell) + if (parent_shell) { - gtk_menu_shell_deactivate_and_emit_done (gtk_menu_shell_get_toplevel_shell (menu_shell)); - return GDK_EVENT_STOP; + /* If a submenu was just activated, it is its shell which is receiving + * the button release event. In this case, we must check the parent + * shell to know about the submenu state. + */ + activated_submenu = parent_shell->priv->activated_submenu; + parent_shell->priv->activated_submenu = FALSE; } - if ((time - priv->activate_time) <= MENU_SHELL_TIMEOUT) + if (priv->parent_menu_shell && + (time - GTK_MENU_SHELL (priv->parent_menu_shell)->priv->activate_time) < MENU_SHELL_TIMEOUT) { - /* We only ever want to prevent deactivation on the first - * press/release. Setting the time to zero is a bit of a - * hack, since we could be being triggered in the first - * few fractions of a second after a server time wraparound. - * the chances of that happening are ~1/10^6, without - * serious harm if we lose. + /* The button-press originated in the parent menu bar and we are + * a pop-up menu. It was a quick press-and-release so we don't want + * to activate an item but we leave the popup in place instead. + * https://bugzilla.gnome.org/show_bug.cgi?id=703069 */ - priv->activate_time = 0; + GTK_MENU_SHELL (priv->parent_menu_shell)->priv->activate_time = 0; return GDK_EVENT_STOP; } - menu_item = gtk_get_event_target_with_type ((GdkEvent *) event, GTK_TYPE_MENU_ITEM); - - if (menu_item) + if (priv->active) { - GtkWidget *submenu = GTK_MENU_ITEM (menu_item)->priv->submenu; - GtkWidget *parent_menu_item_shell = gtk_widget_get_parent (menu_item); + GtkWidget *menu_item; + gint button = priv->button; - if (!_gtk_menu_item_is_selectable (GTK_WIDGET (menu_item))) - return GDK_EVENT_STOP; + priv->button = 0; - if (submenu == NULL) + if (button && (new_button != button) && priv->parent_menu_shell) { - gtk_menu_shell_activate_item (menu_shell, GTK_WIDGET (menu_item), TRUE); + gtk_menu_shell_deactivate_and_emit_done (gtk_menu_shell_get_toplevel_shell (menu_shell)); return GDK_EVENT_STOP; } - else if (GTK_MENU_SHELL (parent_menu_item_shell)->priv->parent_menu_shell && - (activated_submenu || - GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement != GTK_TOP_BOTTOM)) - { - GTimeVal *popup_time; - gint64 usec_since_popup = 0; - popup_time = g_object_get_data (G_OBJECT (menu_shell), - "gtk-menu-exact-popup-time"); - if (popup_time) - { - GTimeVal current_time; + if ((time - priv->activate_time) <= MENU_SHELL_TIMEOUT) + { + /* We only ever want to prevent deactivation on the first + * press/release. Setting the time to zero is a bit of a + * hack, since we could be being triggered in the first + * few fractions of a second after a server time wraparound. + * the chances of that happening are ~1/10^6, without + * serious harm if we lose. + */ + priv->activate_time = 0; + return GDK_EVENT_STOP; + } - g_get_current_time (¤t_time); + menu_item = gtk_get_event_target_with_type (event, GTK_TYPE_MENU_ITEM); - usec_since_popup = ((gint64) current_time.tv_sec * 1000 * 1000 + - (gint64) current_time.tv_usec - - (gint64) popup_time->tv_sec * 1000 * 1000 - - (gint64) popup_time->tv_usec); + if (menu_item) + { + GtkWidget *submenu = GTK_MENU_ITEM (menu_item)->priv->submenu; + GtkWidget *parent_menu_item_shell = gtk_widget_get_parent (menu_item); - g_object_set_data (G_OBJECT (menu_shell), - "gtk-menu-exact-popup-time", NULL); - } + if (!_gtk_menu_item_is_selectable (GTK_WIDGET (menu_item))) + return GDK_EVENT_STOP; - /* Only close the submenu on click if we opened the - * menu explicitly (usec_since_popup == 0) or - * enough time has passed since it was opened by - * GtkMenuItem's timeout (usec_since_popup > delay). - */ - if (!activated_submenu && - (usec_since_popup == 0 || - usec_since_popup > MENU_POPDOWN_DELAY * 1000)) + if (submenu == NULL) { - _gtk_menu_item_popdown_submenu (menu_item); + gtk_menu_shell_activate_item (menu_shell, GTK_WIDGET (menu_item), TRUE); + return GDK_EVENT_STOP; } - else + else if (GTK_MENU_SHELL (parent_menu_item_shell)->priv->parent_menu_shell && + (activated_submenu || + GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement != GTK_TOP_BOTTOM)) { - gtk_menu_item_select (GTK_MENU_ITEM (menu_item)); + GTimeVal *popup_time; + gint64 usec_since_popup = 0; + + popup_time = g_object_get_data (G_OBJECT (menu_shell), + "gtk-menu-exact-popup-time"); + if (popup_time) + { + GTimeVal current_time; + + g_get_current_time (¤t_time); + + usec_since_popup = ((gint64) current_time.tv_sec * 1000 * 1000 + + (gint64) current_time.tv_usec - + (gint64) popup_time->tv_sec * 1000 * 1000 - + (gint64) popup_time->tv_usec); + + g_object_set_data (G_OBJECT (menu_shell), + "gtk-menu-exact-popup-time", NULL); + } + + /* Only close the submenu on click if we opened the + * menu explicitly (usec_since_popup == 0) or + * enough time has passed since it was opened by + * GtkMenuItem's timeout (usec_since_popup > delay). + */ + if (!activated_submenu && + (usec_since_popup == 0 || + usec_since_popup > MENU_POPDOWN_DELAY * 1000)) + { + _gtk_menu_item_popdown_submenu (menu_item); + } + else + { + gtk_menu_item_select (GTK_MENU_ITEM (menu_item)); + } + + return GDK_EVENT_STOP; } - - return GDK_EVENT_STOP; } + + gtk_menu_shell_deactivate_and_emit_done (gtk_menu_shell_get_toplevel_shell (menu_shell)); } - gtk_menu_shell_deactivate_and_emit_done (gtk_menu_shell_get_toplevel_shell (menu_shell)); + return GDK_EVENT_STOP; } - return GDK_EVENT_STOP; + return GDK_EVENT_PROPAGATE; } void -- 2.30.2